package view;

import model.User;
import service.GradeService;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

//张家亦
// PersonalGradePanel类继承自JPanel，用于展示个人成绩相关的界面内容，比如以表格形式呈现成绩信息等
public class PersonalGradePanel extends JPanel {

    // 定义标题字体，使用微软雅黑，加粗，字号为14
    private static final Font TITLE_FONT = new Font("微软雅黑", Font.BOLD, 14);
    // 定义内容字体，使用微软雅黑，常规样式，字号为13
    private static final Font CONTENT_FONT = new Font("微软雅黑", Font.PLAIN, 13);

    // 当前登录的用户对象，用于获取对应此用户的成绩信息
    private User currentUser;
    // 用于展示成绩数据的表格组件
    private JTable gradeTable;
    // 表格的数据模型，用于管理表格中的数据（行、列等相关操作）
    private DefaultTableModel tableModel;
    // 成绩服务类的对象，用于调用获取成绩相关的业务逻辑方法，比如从数据库等数据源获取成绩数据
    private GradeService gradeService;

    // 构造函数，接收当前登录用户对象作为参数，用于初始化个人成绩面板相关的内容
    public PersonalGradePanel(User currentUser) {
        this.currentUser = currentUser;
        // 创建成绩服务类的实例，用于后续获取成绩数据的操作
        this.gradeService = new GradeService();
        // 初始化组件，如布局、表格等相关设置
        initComponents();
        // 加载成绩数据到表格中
        loadGrades();
    }

    // 此方法用于初始化界面组件，包括设置布局、创建表格以及相关的表格样式等操作
    private void initComponents() {
        // 设置面板的布局为BorderLayout，水平和垂直间距都为10像素
        setLayout(new BorderLayout(10, 10));
        // 设置面板的边框为一个空边框，四周的内边距都为10像素，让界面看起来更美观、规整
        setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 创建成绩表格
        // 定义表格的列名数组，分别表示课程、成绩、考试类型、考试日期这几列信息
        String[] columnNames = {"课程", "成绩", "考试类型", "考试日期"};
        // 创建默认的表格数据模型，传入列名数组和初始行数（这里初始行数为0，表示一开始表格为空）
        tableModel = new DefaultTableModel(columnNames, 0) {
            // 重写此方法，用于控制表格单元格是否可编辑，这里返回false，表示学生不能编辑成绩（单元格不可编辑状态）
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        // 使用创建好的数据模型创建JTable表格对象
        gradeTable = new JTable(tableModel);
        // 设置表格内容的字体为之前定义的CONTENT_FONT（微软雅黑，常规样式，字号为13）
        gradeTable.setFont(CONTENT_FONT);
        // 设置表格头部（列名所在行）的字体为之前定义的TITLE_FONT（微软雅黑，加粗，字号为14）
        gradeTable.getTableHeader().setFont(TITLE_FONT);
        // 设置表格每行的高度为25像素，使表格显示更整齐
        gradeTable.setRowHeight(25);

        // 将带有滚动条的表格添加到面板的中间区域（BorderLayout.CENTER），以便在数据较多时可以滚动查看
        add(new JScrollPane(gradeTable), BorderLayout.CENTER);
    }

    // 此方法用于加载成绩数据到表格中，先清空表格已有数据，再从数据源获取数据并填充到表格
    private void loadGrades() {
        // 清空表格已有数据，通过循环删除每一行，直到表格的行数为0
        while (tableModel.getRowCount() > 0) {
            tableModel.removeRow(0);
        }

        // 使用成绩服务类的方法，根据当前用户的ID获取个人成绩数据，返回的数据是一个包含多个成绩记录的列表，
        // 每个成绩记录是一个Map，键值对形式存储成绩相关的各个字段（如课程名、成绩分数、考试类型、考试日期等）
        List<Map<String, Object>> grades = gradeService.getPersonalGrades(currentUser.getId());

        // 遍历获取到的成绩列表，将每条成绩记录填充到表格的数据模型中，从而在表格中显示出来
        for (Map<String, Object> grade : grades) {
            // 从成绩记录的Map中取出相应字段的值，组成一行数据数组
            Object[] row = {
                    grade.get("subjectName"),
                    // 将成绩分数格式化为保留两位小数的字符串形式，再添加到行数据数组中
                    String.format("%.2f", grade.get("score")),
                    grade.get("examType"),
                    // 如果考试日期不为空，则将其格式化为"yyyy-MM-dd"形式的字符串，否则设置为空字符串，然后添加到行数据数组中
                    grade.get("examDate")!= null?
                            new SimpleDateFormat("yyyy-MM-dd").format((Date) grade.get("examDate")) : ""
            };
            // 将这一行数据添加到表格的数据模型中，这样表格就会显示这一行成绩信息了
            tableModel.addRow(row);
        }
    }
}